package com.learning.servlet3x.async;

import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

/**
 * ClassName: AsyncSupportedServlet
 * Description: Servlet3x新特性：支持异步的 Servlet。 asyncSupported = true
 * Date:  2014/12/06 16:56 【需求编号】
 *
 * @author Sam Sho
 * @version V1.0.0
 */
@WebServlet(name = "AsyncSupportedServlet", value = {"/asyncSupportedServlet"}, asyncSupported = true)
public class AsyncSupportedServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter out = resp.getWriter();
        out.println("进入Servlet的时间：" + new Date() + ".");
        out.flush();

        // 在子线程中执行业务调用，并由其负责输出响应，主线程退出
        AsyncContext ctx = req.startAsync();

        // 添加异步监听器
        ctx.addListener(new AsyncSupportListener());

        //设置异步调用超时时长
        ctx.setTimeout(30 * 3000);
        //启动异步调用的线程
        ctx.start(new Executor(ctx));

        out.println("结束Servlet的时间：" + new Date() + ".");
        out.flush();
    }

    /**
     * 子线程，模拟业务处理
     */
    public static class Executor implements Runnable {
        private AsyncContext ctx;

        public Executor(AsyncContext ctx) {
            this.ctx = ctx;
        }

        @Override
        public void run() {
            try {
                //等待十秒钟，以模拟业务方法的执行
                Thread.sleep(10000);
                PrintWriter out = ctx.getResponse().getWriter();
                out.println("业务处理完毕的时间：" + new Date() + ".");
                out.flush();
                ctx.complete();
            } catch (Exception e) {
            }
        }
    }
}
